package com.atguigu.userservice.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.util.UuidUtils;
import com.atguigu.commonutils.utils.GuliException;
import com.atguigu.commonutils.utils.HttpContext;
import com.atguigu.commonutils.utils.JwtTokenUtil;
import com.atguigu.commonutils.utils.LoginUser;
import com.atguigu.commonutils.utils.LoginUserUtil;
import com.atguigu.commonutils.utils.MD5Utils;
import com.atguigu.userservice.entity.UcenterMember;
import com.atguigu.userservice.mapper.UcenterMemberMapper;
import com.atguigu.userservice.service.UcenterMemberService;
import com.atguigu.userservice.utils.WxConstUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author Mr.Alan
 * @since 2020-08-27
 */
@Service
public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService {
    @Resource
    private RedisTemplate<String, Serializable> jsonRedisTemplate;

    @Override
    public int register(UcenterMember ucenterMember) {
        if (StringUtils.isEmpty(ucenterMember.getNickname())) {
            ucenterMember.setNickname(String.format("用户%s", UuidUtils.generateUuid().replace("-", "")));
        }
        Date now = DateUtil.date();
        ucenterMember.setGmtCreate(now)
                .setGmtModified(now);
        // 密码加密
        ucenterMember.setPassword(MD5Utils.encryptPassWord(ucenterMember.getPassword()));
        return getBaseMapper().insert(ucenterMember);
    }

    @Override
    public String login(UcenterMember ucenterMember) {

        UcenterMember dbUser = super.lambdaQuery().eq(UcenterMember::getMobile, ucenterMember.getMobile()).one();
        if (ObjectUtils.isNull(dbUser)) {
            throw new GuliException(20001, "用户不存在");
        }
        if (MD5Utils.mismatch(dbUser.getPassword(), ucenterMember.getPassword())) {
            throw new GuliException(20001, "密码错误");
        }
        if (dbUser.getIsDisabled()) {
            throw new GuliException(20001, "当前用户已被禁用");
        }
        return getToken(dbUser);
    }

    @Override
    public LoginUser getInfo() {
        return LoginUserUtil.getLoginUser();
    }

    @Override
    public boolean updateInfo(UcenterMember ucenterMember) {
        ucenterMember.setPassword(null);
        return super.updateById(ucenterMember);
    }

    @Override
    public String loginByPhone(String phone, String code) {

        String dbCode = Convert.toStr(jsonRedisTemplate.opsForValue().get(String.format("sms:phone:login:%s", phone)));
        if (!code.equals(dbCode)) {
            throw new GuliException(20001, "验证码不正确");
        }
        UcenterMember dbUser = super.lambdaQuery().eq(UcenterMember::getMobile, phone).one();
        if (ObjectUtils.isNull(dbUser)) {
            throw new GuliException(20001, "用户不存在");
        }
        jsonRedisTemplate.delete(String.format("sms:phone:login:%s", phone));
        return getToken(dbUser);
    }

    private String getToken(UcenterMember dbUser) {
        LoginUser loginUser = new LoginUser();
        loginUser.setId(dbUser.getId())
                .setPhone(dbUser.getMobile())
                .setName(dbUser.getNickname())
                .setStatus(1)
                .setAvatar(dbUser.getAvatar())
                .setLastLoginTime(DateUtil.date().getTime())
                .setOpenid(dbUser.getOpenid());
        String token = JwtTokenUtil.generateToken(dbUser.getId(), DateUtil.date().getTime());
        loginUser.login();
        return token;
    }

    @Override
    public boolean logout() {
        LoginUser loginUser = LoginUserUtil.getLoginUser();
        return loginUser.logout();
    }

    @Override
    public String loginByWx(String code) {

        String url = null;
        try {

            // 01 通过 code 获取 用户的openId
            url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
            url = String.format(url, WxConstUtils.APP_ID, WxConstUtils.APP_SECRET, code);
            String response = HttpContext.get(url, true);
            Map<String, String> result = Convert.toMap(String.class, String.class, JSONObject.parse(response));
            String openid = result.get("openid");

            if (StringUtils.isNotEmpty(openid)) {
                UcenterMember dbUser = super.lambdaQuery().eq(UcenterMember::getOpenid, openid).one();
                if (ObjectUtils.isNotNull(dbUser)) {
                    // 02 旧用户登录
                    return loginForOldUser(dbUser);
                } else {
                    // 03 新用登录
                    return loginForNewUser(result, openid);
                }
            } else {
                throw new GuliException(20001, "登录失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GuliException(20001, "登录失败");
        }

    }

    /**
     * 新用户登录
     */
    private String loginForNewUser(Map<String, String> result, String openid) throws Exception {

        String url;
        String response;
        String accessToken = result.get("access_token");
        // 03 空则说明第一次登录,将用户的信息添加到数据库中
        url = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        url = String.format(url, accessToken, openid);
        response = HttpContext.get(url, true);
        result = Convert.toMap(String.class, String.class, JSONObject.parse(response));
        System.out.println("result = " + result);
        UcenterMember newUser = new UcenterMember();
        newUser.setOpenid(result.get("openid"))
                .setAvatar(result.get("headimgurl"))
                .setNickname(result.get("nickname"))
                .setGmtCreate(DateUtil.date())
                .setGmtModified(DateUtil.date());
        super.save(newUser);
        LoginUser loginUser = new LoginUser();
        loginUser.setId(newUser.getId())
                .setAvatar(newUser.getAvatar())
                .setName(newUser.getNickname())
                .setStatus(1)
                .setLastLoginTime(DateUtil.date().getTime())
                .setOpenid(newUser.getOpenid());
        loginUser.login();
        return JwtTokenUtil.generateToken(newUser.getId(), DateUtil.date().getTime());

    }

    /**
     * 旧用户登录
     */
    private String loginForOldUser(UcenterMember dbUser) {

        LoginUser loginUser = new LoginUser();
        loginUser.setId(dbUser.getId())
                .setAvatar(dbUser.getAvatar())
                .setPhone(dbUser.getMobile())
                .setName(dbUser.getNickname())
                .setStatus(1)
                .setAvatar(dbUser.getAvatar())
                .setLastLoginTime(DateUtil.date().getTime())
                .setOpenid(dbUser.getOpenid());
        loginUser.login();
        return JwtTokenUtil.generateToken(dbUser.getId(), DateUtil.date().getTime());

    }
}
